﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;

using System.Xml.Serialization;
using System.IO;
using System.Xml;

using System.Text.RegularExpressions;


namespace integrationServer
{
    public partial class Form1 
    {
        #region statement
        public bool tabOk = false;
        public bool white_black;
        public string url;
        public List<User> listUser = new List<User>();
        public List<Board> listBoard = new List<Board>();
        #endregion

        #region builder
        public Form1()
        {
            ChargementDonnee();
        }
        #endregion

        #region Data loading
        public void ChargementDonnee()
        {
            try
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(List<Board>));
                TextReader textReader = new StreamReader(Directory.GetCurrentDirectory() + @"\saveBoard.xml");
                listBoard = (List<Board>)deserializer.Deserialize(textReader);
                textReader.Close();
            }
            catch (Exception )
            {               
            }

            for (int i = 0; i < listBoard.Count; i++)
            {               
            }

            try
            {
                XmlSerializer deserializer2 = new XmlSerializer(typeof(List<User>));
                TextReader textReader2 = new StreamReader(Directory.GetCurrentDirectory() + @"\saveUser.xml");
                listUser = (List<User>)deserializer2.Deserialize(textReader2);
                textReader2.Close();
            }
            catch (Exception)
            {
            }          
        }
        #endregion

        #region Resource: 

        #region Create new user
        public int CreerUser(string nom, string pseudo, string password,string url)
        {
            User testUser = new User(nom, pseudo, password,url);

            #region Empty list
            if (listUser.Count == 0)
            {
                listUser.Add(testUser);

                #region save new data
                try
                {
                    XmlSerializer serializerUser = new XmlSerializer(typeof(List<User>));
                    TextWriter textWriterUser = new StreamWriter(Directory.GetCurrentDirectory() + @"\saveUser.xml");
                    serializerUser.Serialize(textWriterUser, listUser);
                    textWriterUser.Close();
                    return 1;
                }
                catch (Exception)
                {
                    return 0;
                }
                #endregion
            }
            #endregion
            else
            {
                for (int i = 0; i < listUser.Count; i++)
                {
                    if (pseudo == listUser[i].name)
                    {
                        return 0;
                    }
                }
                    
                listUser.Add(testUser);

                #region save new data
                try
                {
                    XmlSerializer serializerUser = new XmlSerializer(typeof(List<User>));
                    TextWriter textWriterUser = new StreamWriter(Directory.GetCurrentDirectory() + @"\SaveUser.xml");
                    serializerUser.Serialize(textWriterUser, listUser);
                    textWriterUser.Close();
                    return 1;
                }
                catch (Exception)
                {
                }
                return 0;
                #endregion
            }
        }
        #endregion

        public string ListerUser()
        {
            try
            {
                String XmlizedString = null;
                UserListResponse pObjectUser = new UserListResponse();
                XmlRootAttribute xRoot = new XmlRootAttribute("goimerir");
                for (int i = 0; i < listUser.Count; i++)
                {
                    pObjectUser.user.Add(new UserListResponse.CompactUserModel(listUser[i]));
                }
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(UserListResponse), xRoot);
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                xs.Serialize(xmlTextWriter, pObjectUser);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                return XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
            }
            catch (Exception)
            {
                return null;
            }
           
        }

        #endregion

        #region Resource: Board

        #region create new board
        public int CreerBoard(string pseudoUser1, string pseudoUser2, string nameBoard, string size, bool color)
        {
            if (pseudoUser1 != "" && nameBoard != "")
            {
                if (size == "")
                {
                    size = "9x9";
                }

                if (color == null)
                {
                    color = true;
                }

                Board testBoard = new Board(pseudoUser1, pseudoUser2, nameBoard, size, DateTime.Now, color);

                if (pseudoUser2 == "")
                {
                    testBoard.status = "OPEN";
                }
                else
                {
                    testBoard.status = "FULL";
                }

                listBoard.Add(testBoard);

                #region save new data
                try
                {
                    XmlSerializer serializerBoard = new XmlSerializer(typeof(List<Board>));
                    TextWriter textWriterBoard = new StreamWriter(Directory.GetCurrentDirectory() + @"\SaveBoard.xml");
                    serializerBoard.Serialize(textWriterBoard, listBoard);
                    textWriterBoard.Close();
                    return 1;
                }
                catch (Exception)
                {
                    return 0;
                }
                #endregion
            }
            else
            {
                return 2;
            }
        }
        #endregion

        #region Delete board
        public int EffacerBoard(string nameBoard)
        {
            for (int i = 0; i < listBoard.Count; i++)
            {
                if (listBoard[i].Name == nameBoard)
                {
                    listBoard.Remove(listBoard[i]);
                    
                    return 1;
                }
            }
            return 0;
        }
        #endregion

        #region List board
        public string ListerBoard()
        {
            #region serializer
            try
            {
                String XmlizedString = null;
                BoardsListResponse pObjectBoard = new BoardsListResponse();
                XmlRootAttribute xRoot = new XmlRootAttribute("goimerir");
                for (int i = 0; i < listBoard.Count; i++)
                {
                    pObjectBoard.listBoards.Add(new BoardsListResponse.CompactBoardListModel(listBoard[i]));
                }
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(BoardsListResponse), xRoot);
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                xs.Serialize(xmlTextWriter, pObjectBoard);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                return XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
            }
            catch (Exception)
            {
                return null;
            }
            #endregion
        }
        #endregion

        #region List one board
        public string lister1Board(string board)
        {
            #region sérializer
            try
            {
                String XmlizedString = null;
                BoardResponse pObjectBoard = new BoardResponse();
                XmlRootAttribute xRoot = new XmlRootAttribute("goimerir");
                for (int i = 0; i < listUser.Count; i++)
                {
                    if (listBoard[i].Name == board)
                    {
                        pObjectBoard.boards.Add(new BoardResponse.CompactBoardModel(listBoard[i]));
                    }
                }
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(BoardResponse), xRoot);
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                xs.Serialize(xmlTextWriter, pObjectBoard);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                return XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
            }
            catch (Exception)
            {
                return null;
            }
            #endregion
        }
        #endregion

        #endregion

        #region Game

        #region invite user join board
        public int InviteUserJoinBoard(string user, string invite, string board)
        {
            if (user != "" && invite != "" && board != "")
            {
                for (int i = 0; i < listUser.Count; i++)
                {
                    if (user == listUser[i].name)
                    {
                        for (int j = 0; j < listBoard.Count; j++)
                        {
                            if (listBoard[j].Name == board && listBoard[j].owner == user && listBoard[j].status == "OPEN")
                            {
                                listBoard[j].invite = invite;
                                listBoard[j].status = "FULL";
                                return 1;
                            }
                        }
                        return 0;
                    }
                    else
                    {
                        return 2;
                    }
                }
                return 2;
            }
            else
            {
                return 3;
            }
        }
        #endregion

        #region Permission to join
        public int PermissionToJoin(string j1,string board)
        {
            if (j1 != "" && board != "")
            {
                for (int i = 0; i < listBoard.Count; i++)
                {
                    if (listBoard[i].Name == board && listBoard[i].owner != j1)
                    {
                        if (listBoard[i].status == "OPEN")
                        {
                            return 1;
                        }
                        else
                        {
                            return 0;
                        }
                    }
                }
                return 4;
            }
            else
            {
                return  2;
            }
        }
        #endregion

        #region play one move
        public int MovePlay(int row, int column,string board)
        {
            for (int i = 0; i < listBoard.Count; i++)
            {
                if (listBoard[i].Name == board && listBoard[i].status !="CLOSE")
                {
                    #region Test if the board has to be closed
                    if ((listBoard[i - 1].listMove.Last().Column == null && listBoard[i - 1].listMove.Last().Row == null) && (row == null && column == null))
                    {
                        listBoard[i].status = "CLOSE";
                        listBoard[i].listMove.Add(new Moves(row, column));
                        return listBoard[i].PostionPoints(row, column);
                    }
                    #endregion
                    else
                    {
                        listBoard[i].listMove.Add(new Moves(row, column));
                        return listBoard[i].PostionPoints(row, column);
                    }
                }
            }
            return 0;
        }
        #endregion

        #region Retrieve a board to play
        public string listHistoryMove(string board)
        {
            try
            {
                String XmlizedString = null;
                BoardResponse pObjectBoard = new BoardResponse();
                XmlRootAttribute xRoot = new XmlRootAttribute("goimerir");
                for (int i = 0; i < listUser.Count; i++)
                {
                    if (listBoard[i].Name == board)
                    {
                        pObjectBoard.boards.Add(new BoardResponse.CompactBoardModel(listBoard[i]));
                    }
                }
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(typeof(BoardResponse), xRoot);
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                xs.Serialize(xmlTextWriter, pObjectBoard);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                return XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
            }
            catch (Exception)
            {
                return null;
            }
        }
        #endregion

        public string ListMoveBard(string board,string start, string stop)
        {
            ListMoveBoardResponse pOjectList = new ListMoveBoardResponse();
            XmlRootAttribute xRoot = new XmlRootAttribute("goimerir");
            XmlSerializer xs = new XmlSerializer(typeof(Board),xRoot);
            MemoryStream memoryStream = new MemoryStream();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
            String XmlizedString = null;

            if (start == "" && stop == "")
            {
                for (int i = 0; i < listBoard.Count; i++)
                {
                    if (listBoard[i].Name == board)
                    {
                        xs.Serialize(xmlTextWriter, listBoard[i].listMove);
                        memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                        return XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());

                    }
                }
                return null;
            }
            else if (start != "" && stop != "")
            {
                for (int i = 0; i < listBoard.Count; i++)
                {
                    if (listBoard[i].Name == board)
                    {
                        if (Convert.ToInt32(stop) < listBoard[i].listMove.Count)
                        {
                            for (int j = Convert.ToInt32(start); j < Convert.ToInt32(stop); j++)
                            {
                                pOjectList.boards.Add(new ListMoveBoardResponse.Compact1BoardModel(listBoard[i].listMove[j]));
                            }
                            xs.Serialize(xmlTextWriter, pOjectList);
                            memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                            return XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
            }
            else if ((start != "" && stop == "") || (start == "" && stop != ""))
            {
                return null;
            }
            return null;
        }


        #region encoding UTF8
        private static String UTF8ByteArrayToString(Byte[] characters)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            String constructedString = encoding.GetString(characters);
            return (constructedString);
        }
        #endregion
    }
        #endregion
}
